import { takeByteArray2int,protocal_head } from "./protocol.js"
import dipatch from "./dipatch.js"
class Res {
  constructor() {
    // 一帧数据
    this.data = []
    // 数据内容长度
    this.dataLength = 0
    // 数据内容
    this.content = []
  }
  push(a) {
    if (a instanceof Array) {
      this.data.push(...a)
    } else {
      this.data.push(a)
    }
  }

  setDataLength(dataLength) {
    this.dataLength = dataLength
  }

  setContent(content) {
    this.content = [...content]
  }
}

class ByteBuf {
  constructor() {
    this.buf = []
    this.markedReaderIndex = 0
    this.readerIndex = 0
    this.writerIndex = 0
    this.interval = 1000
    this.time = this.startTime()
  }
  startTime() {
    if (!this.time) {
      setInterval(() => {
        // console.log('time', this);
        if (this.parse()) this.discard()
      }, this.interval)
    }
  }

  markReaderIndex() {
    this.markedReaderIndex = this.readerIndex
  }

  resetReaderIndex() {
    this.readerIndex = this.markedReaderIndex
    this.markedReaderIndex = 0
  }

  // 写字节
  write(data) {
    this.writerIndex += data.length
    this.buf.push(...data)
  }

  // 读取一个字节
  readByte() {
    let b = this.buf[this.readerIndex]
    this.readerIndex += 1
    return b
  }

  // 读取 count 个字节
  read(count) {
    let start = this.readerIndex
    let end = this.readerIndex + count
    this.readerIndex += count
    return this.buf.slice(start, end)
  }

  // 可读字节数
  readableBytes() {
    return this.writerIndex - this.readerIndex
  }

  /**
   * 解析数据
   * 返回 true 表示解析出数据
   */
  parse() {
    if (this.readableBytes() < 26) return false
    this.markReaderIndex()    
    for (let i = 0; i < protocal_head.length; i++) {
      let a = this.readByte()
      if (a != protocal_head[i]) {
        this.discard()
        return false
      }
    }
    let res = new Res()
    res.push(protocal_head)
    res.push(this.read(18))

    // 数据长度
    let dataLengthArray = this.read(2)
    res.push(dataLengthArray)
    let dataLength = takeByteArray2int(dataLengthArray)
    console.log("长度= " + dataLength)
    res.setDataLength(dataLength)
    if (dataLength + 2 > this.readableBytes()) {
      this.resetReaderIndex()
      return false
    }
    // 数据内容
    let content = this.read(dataLength)
    res.push(content)
    res.setContent(content)

    // 2个校验位
    res.push(this.read(2))

    // 入库
    this.insertDb(res)
    return true
  }

  // 入库
  insertDb(res) {
    dipatch.handler(res)
  }

  // 丢弃已解析的数据
  discard() {
    if (this.readerIndex > 0) {
      let d = this.buf.splice(0, this.readerIndex)
      console.log('discard= ',d);
      this.readerIndex = 0
      this.writerIndex = this.buf.length
    }
  }

  decode(data) {
    this.write(data)
  }
}
export default new ByteBuf()
